#pragma once
#include <iostream>
#include <string>
#include <mysql/mysql.h>
#include "../comm/httplib.h"
#include <jsoncpp/json/json.h>

#include "head_mysql.hpp"

using namespace httplib;


// MySQL connection details
const char *db_host = "127.0.0.1";
const char *db_user = "oj_client";
const char *db_pass = "123456";
const char *db_name = "oj";
unsigned int db_port = 3306;

// MYSQL *connect_db()
// {
//     MYSQL *conn = mysql_init(nullptr);
//     if (conn == nullptr)
//     {
//         std::cerr << "mysql_init() failed\n";
//         return nullptr;
//     }

//     if (mysql_real_connect(conn, db_host, db_user, db_pass, db_name, db_port, nullptr, 0) == nullptr)
//     {
//         std::cerr << "mysql_real_connect() failed\n";
//         mysql_close(conn);
//         return nullptr;
//     }
//     //设置字符集
//     mysql_set_character_set(conn, "utf8");
//     return conn;
// }

void handle_register(const Request &req, Response &res)
{
    Json::Reader reader;
    Json::Value json_req;
    reader.parse(req.body, json_req);
    std::string username = json_req["username"].asString();
    std::string password = json_req["password"].asString();

    MYSQL *conn = connect_db();
    if (conn == nullptr)
    {
        res.set_content("Database connection failed", "text/plain");
        res.status = 500;
        return;
    }

    // Use prepared statements to prevent SQL injection
    MYSQL_STMT *stmt;
    MYSQL_BIND bind[2];

    stmt = mysql_stmt_init(conn);
    if (!stmt)
    {
        std::cerr << "mysql_stmt_init() failed\n";
        res.set_content("Registration failed", "text/plain");
        res.status = 500;
        mysql_close(conn);
        return;
    }

    const char *query = "INSERT INTO users (username, password) VALUES (?, ?)";
    if (mysql_stmt_prepare(stmt, query, strlen(query)))
    {
        std::cerr << "mysql_stmt_prepare() failed\n";
        res.set_content("Registration failed", "text/plain");
        res.status = 500;
        mysql_stmt_close(stmt);
        mysql_close(conn);
        return;
    }

    memset(bind, 0, sizeof(bind));

    bind[0].buffer_type = MYSQL_TYPE_STRING;
    bind[0].buffer = (char *)username.c_str();
    bind[0].buffer_length = username.size();

    bind[1].buffer_type = MYSQL_TYPE_STRING;
    bind[1].buffer = (char *)password.c_str();
    bind[1].buffer_length = password.size();

    mysql_stmt_bind_param(stmt, bind);

    if (mysql_stmt_execute(stmt))
    {
        std::cerr << "mysql_stmt_execute() failed\n";
        res.set_content("Registration failed", "text/plain");
        res.status = 500;
    }
    else
    {
        res.set_content("Registration successful", "text/plain");
    }

    mysql_stmt_close(stmt);
    mysql_close(conn);
}

void handle_login(const Request &req, Response &res)
{
    Json::Reader reader;
    Json::Value json_req;
    reader.parse(req.body, json_req); // 解析请求体中的 JSON 数据
    std::string username = json_req["username"].asString();
    std::string password = json_req["password"].asString();

    MYSQL *conn = connect_db(); // 连接到数据库
    if (conn == nullptr)
    {
        res.set_content("{\"success\": false, \"message\": \"Database connection failed\"}", "application/json");
        res.status = 500;
        return;
    }

    // 使用预处理语句防止 SQL 注入
    MYSQL_STMT *stmt;
    MYSQL_BIND bind[2], result_bind[1];

    stmt = mysql_stmt_init(conn);
    if (!stmt)
    {
        std::cerr << "mysql_stmt_init() failed\n";
        res.set_content("{\"success\": false, \"message\": \"Login failed\"}", "application/json");
        res.status = 500;
        mysql_close(conn);
        return;
    }

    const char *query = "SELECT password FROM users WHERE username = ?";
    if (mysql_stmt_prepare(stmt, query, strlen(query)))
    {
        std::cerr << "mysql_stmt_prepare() failed\n";
        res.set_content("{\"success\": false, \"message\": \"Login failed\"}", "application/json");
        res.status = 500;
        mysql_stmt_close(stmt);
        mysql_close(conn);
        return;
    }

    memset(bind, 0, sizeof(bind));
    bind[0].buffer_type = MYSQL_TYPE_STRING;
    bind[0].buffer = (char *)username.c_str();
    bind[0].buffer_length = username.size();

    mysql_stmt_bind_param(stmt, bind);

    if (mysql_stmt_execute(stmt))
    {
        std::cerr << "mysql_stmt_execute() failed\n";
        res.set_content("{\"success\": false, \"message\": \"Login failed\"}", "application/json");
        res.status = 500;
        mysql_stmt_close(stmt);
        mysql_close(conn);
        return;
    }

    // 绑定结果
    char db_password[256];
    memset(result_bind, 0, sizeof(result_bind));
    result_bind[0].buffer_type = MYSQL_TYPE_STRING;
    result_bind[0].buffer = db_password;
    result_bind[0].buffer_length = sizeof(db_password);

    mysql_stmt_bind_result(stmt, result_bind);

    if (mysql_stmt_fetch(stmt) == 0) // 有结果
    {
        // 这里假设数据库中存储的是明文密码
        // 在实际应用中，应该使用哈希密码，并进行相应的哈希对比
        if (password == db_password)
        {
            // 登录成功，设置 Cookie
            res.set_header("Set-Cookie", "sessionid=123456; Path=/;Max-Age=3600");
            res.set_content("{\"success\": true}", "application/json");
        }
        else
        {
            res.set_content("{\"success\": false, \"message\": \"Invalid username or password\"}", "application/json");
        }
    }
    else
    {
        res.set_content("{\"success\": false, \"message\": \"Invalid username or password\"}", "application/json");
    }

    mysql_stmt_close(stmt);
    mysql_close(conn);
}
